package com.devo.icecream.data

import com.devo.icecream.AppLogger
import com.devo.icecream.BuildConfig
import com.devo.icecream.exception.APIException
import com.devo.icecream.utils.MachineKeyInterceptor
import com.google.gson.Gson
import okhttp3.OkHttpClient
import okhttp3.internal.platform.Platform
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.X509TrustManager

object APIClient {

    private const val BASE_URL = "https://123.kalukali.com/"
    private val logger = HttpLoggingInterceptor.Logger { message ->
        if (BuildConfig.DEBUG) {
            if (message.startsWith('{') && message.endsWith("}")) {
                AppLogger.json(message)
            } else {
                Platform.get().log(message)
            }
        }
    }
    private val gson = Gson()

    private val trustManager by lazy {
        object : X509TrustManager {
            override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {
            }

            override fun checkServerTrusted(p0: Array<out X509Certificate>?, p1: String?) {
            }

            override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
        }
    }

    private val sslContext by lazy {
        SSLContext.getInstance("SSL").apply {
            init(null, arrayOf(trustManager), SecureRandom())
        }
    }

    private val hostnameVerifier by lazy {
        HostnameVerifier { _, _ -> true }
    }

    private val okHttpClient by lazy {
        OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor(logger).apply {
                if (BuildConfig.DEBUG) {
                    setLevel(HttpLoggingInterceptor.Level.BODY)
                } else {
                    setLevel(HttpLoggingInterceptor.Level.NONE)
                }
            })
            .sslSocketFactory(sslContext.socketFactory, trustManager)
            .hostnameVerifier(hostnameVerifier)
            .addInterceptor(MachineKeyInterceptor())
            .callTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build()
    }

    private val retrofit by lazy {
        Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    private val api by lazy {
        retrofit.create(API::class.java)
    }

    //获取电话号码
    suspend fun getServicePhone(): String {
        val telPhone = catchError {
            api.fetchServiceTel()
        }
        return telPhone.data?.get("telNumber") ?: ""
    }

    //获取广告列表
    suspend fun getAdverts(type: Int = 1, page: Int = 1, pageSize: Int = 10): List<Advertising> {
        val adverts = catchError {
            api.fetchAdvertising(type, page, pageSize)
        }
        return adverts.data ?: arrayListOf()
    }

    //获取商品列表
    suspend fun getProducts(page: Int = 1, pageSize: Int = 10): List<ProductBean> {
        val products = catchError {
            api.fetchProducts(page, pageSize)
        }
        return products.data ?: arrayListOf()
    }

    //确认订单
    suspend fun requestOrder(orderDto: OrderDto): OrderBean? {
        val order = catchError {
            api.pushOrder(orderDto)
        }
        return order.data;
    }

    //提取成分
    suspend fun getIngredients(): IngredientDto? {
        val resp = catchError {
            api.fetchIngredient()
        }
        return resp.data
    }

    //上报订单错误,并退款
    suspend fun refundOrder(orderId: String, type: Int): Boolean {
        val resp = catchError {
            api.pushOrderFailure(FailureDto(orderId, type))
        }
        return resp.isSuccess
    }

    //取消订单
    suspend fun cancelOrder(orderId: String): Boolean {
        val resp = catchError {
            api.cancelOrder(orderId)
        }
        return resp.isSuccess
    }

    //结束订单
    suspend fun finishOrder(orderId: String, recipes: Map<String, Float>): Boolean {
        val resp = catchError {
            api.checkOrder(
                CheckOrderDtoBean(
                    orderId = orderId,
                    recipes = recipes.map {
                        CheckOrderDtoBean.RecipeDtoBean(it.key, it.value)
                    }
                )
            )
        }

        return resp.isSuccess
    }

    //获取位置信息
    suspend fun getCellInfo(mcc: Int, mnc: Int, lac: Int, ci: Int): String? {
        val resp: CellLocationResponse? = try {
            gson.fromJson(
                api.getCellInfo(mcc, mnc, lac, ci).msg,
                CellLocationResponse::class.java
            )
        } catch (e: Exception) {
            AppLogger.e("LBS 查询报错", e)
            null
        }

        return resp?.let {
            "%.06f,%.06f".format(it.lon.toFloat(), it.lat.toFloat())
        }

    }


    private suspend fun <T> catchError(block: suspend () -> BaseResponse<T>): BaseResponse<T> {
        return block().also {
            if (it.code != 200 && BuildConfig.DEBUG) {
                AppLogger.e("request error:${it.code}/${it.msg}")
                throw APIException(it.code, it.msg)
            }
        }
    }


}